package webserver.standard;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class HttpRequestHandler implements Handler
{
	private static final String CLRF = "\r\n";
	String firstLine = "";
	String httpversion = "HTTP/1.0";
	BufferedReader in;
	OutputStream out;
	Socket socket;

	public HttpRequestHandler(String firstLine, Socket socket)
	{
		this.socket = socket;
		this.firstLine = firstLine;
	}

	private void errorReport(String code, String title, String msg)
	{
		try
		{
			out
					.write(("HTTP/1.0 "
							+ code
							+ " "
							+ title
							+ "\r\n"
							+ "\r\n"
							+ "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n"
							+ "<TITLE>" + code + " " + title + "</TITLE>\r\n"
							+ "</HEAD><BODY>\r\n" + "<H1>" + title
							+ "</H1>\r\n" + msg + "<P>\r\n"
							+ "<HR><ADDRESS>dDist Webserver 1.0 at "
							+ socket.getLocalAddress().getHostName() + " Port "
							+ socket.getLocalPort() + "</ADDRESS>\r\n" + "</BODY></HTML>\r\n")
							.getBytes());
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	private String guessContentType(String path)
	{
		if (path.endsWith(".html") || path.endsWith(".htm"))
			return "text/html";
		else if (path.endsWith(".txt") || path.endsWith(".java"))
			return "text/plain";
		else if (path.endsWith(".gif"))
			return "image/gif";
		else if (path.endsWith(".class"))
			return "application/octet-stream";
		else if (path.endsWith(".jpg") || path.endsWith(".jpeg"))
			return "image/jpeg";
		else if (path.endsWith(".png"))
			return "image/png";
		else
			return "text/plain";
	}

	private void handleGet(BufferedReader in, String s)
	{
		File f = null;
		String requestUri;
		String status = "";
		String statusline = "";

		if (parseRequest(s))
		{
			requestUri = s.substring(4, s.length() - 9);

			if (!requestUri.equals("/"))
			{
				requestUri = requestUri.substring(1);
			}
			else
			{
				requestUri = "index.html";
			}

			f = new File(requestUri);

			if (f.exists())
			{
				try
				{
					InputStream file = new FileInputStream(f);

					statusline = httpversion + " " + "200 All Ok" + CLRF;
					out.write(statusline.getBytes());
					out.write(("Content-Type: "
							+ this.guessContentType(f.getName()) + CLRF)
							.getBytes());
					sendFile(file, socket.getOutputStream());

				}
				catch (FileNotFoundException e)
				{
					errorReport("404", "Not Found",
							"The requested URL was not found on this server.");

				}
				catch (IOException e)
				{
					errorReport("404", "Not Found",
							"The requested URL was not found on this server.");
				}
			}
			else
			{
				errorReport("404", "Not Found",
						"The requested URL was not found on this server.");
			}
		}
		else
		{
			errorReport("400", "Bad Request",
					"Your browser sent a request that this server could not understand.");
		}
		try
		{
			out.flush();
			out.close();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	private boolean parseRequest(String request)
	{
		return ((request.endsWith("HTTP/1.0") || request.endsWith("HTTP/1.1")));
	}

	public void run()
	{
		String s;
		try
		{
			BufferedReader in = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			out = socket.getOutputStream();

			if (firstLine.startsWith("GET"))
			{
				handleGet(in, firstLine);
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	private void sendFile(InputStream file, OutputStream out)
	{
		int bytes = 0;
		try
		{
			byte[] buffer = new byte[1000];
			while ((bytes = file.read(buffer)) != -1)
				out.write(buffer, 0, bytes);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
}